package cn.iniche.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;

import com.download.library.DownloadImpl;
import com.download.library.DownloadListenerAdapter;
import com.download.library.DownloadTask;
import com.download.library.Extra;

import java.io.File;
import java.util.List;

import javax.microedition.util.ContextHolder;

import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import ru.playsoftware.j2meloader.config.Config;


public final class UpdateUtils {

    private static final String TAG = "UpdateUtils";
    private static final String UPDATE_CHECK_URL = "https://gitee.com/chedanxiong/api/raw/master/JL-Iniche/update.json";


    @SuppressWarnings("ResultOfMethodCallIgnored")
    @SuppressLint("CheckResult")
    public static void checkUpdate(Activity activity, boolean auto) {
        UpdateUtils.check()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new SingleObserver<UpdateBean>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onSuccess(@NonNull UpdateUtils.UpdateBean updateBean) {
                        if (updateBean.hasUpdate) {
                            UpdateUtils.showUpdateDialog(activity, updateBean);
                            return;
                        }

                        if (!auto) {
                            Toast.makeText(activity, "已是最新版本", Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        if (!auto) {
                            Toast.makeText(activity, "检查更新发生错误: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }


    @NonNull
    private static Single<UpdateBean> check() {
        return Single.create(emitter -> {
            final OkHttpClient client = SingletonHelper.getOkHttpClient();

            final Request request = new Request.Builder()
                    .get()
                    .url(UPDATE_CHECK_URL)
                    .build();

            final Response response = client.newCall(request).execute();
            UpdateBean bean = null;
            if (response.isSuccessful()) {
                ResponseBody body = response.body();
                String json = body == null ? null : body.string();
                Log.i(TAG, "doUpdate: json:" + json);
                bean = SingletonHelper.getGson().fromJson(json, UpdateBean.class);
            }

            if (bean != null) {
                if (TextUtils.isEmpty(bean.downloadUrl)) {
                    bean.hasUpdate = false;
                } else {
                    Context context = ContextHolder.getAppContext();
                    PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
                    if (bean.versionCode > info.versionCode) {
                        bean.hasUpdate = true;
                    } else if (bean.versionCode == info.versionCode) {
                        bean.hasUpdate = !TextUtils.isEmpty(bean.versionName) && !TextUtils.equals(bean.versionName, info.versionName);
                    } else {
                        bean.hasUpdate = false;
                    }
                }
            }

            if (bean == null) bean = new UpdateBean();

            emitter.onSuccess(bean);

        });
    }


    private static void showUpdateDialog(Context context, UpdateBean bean) {
        StringBuilder message = new StringBuilder();
        message.append("新版本: ").append(bean.versionName).append("\n\n");
        if (bean.changeLog != null && bean.changeLog.size() > 0) {
            for (String log : bean.changeLog) {
                message.append(log).append('\n');
            }
        } else {
            message.append("无更新说明\n");
        }
        message.append("\n是否立即更新?");
        AlertDialog.Builder builder = new AlertDialog.Builder(context)
                .setTitle("发现新版本")
                .setMessage(message)
                .setPositiveButton("后台下载", (d, w) -> doUpdateAction(context, bean))
                .setNegativeButton(android.R.string.cancel, null);
        builder.show();
    }


    private static void doUpdateAction(Context context, UpdateBean bean) {

        File file = new File(Config.getDownloadDir());
        if (!file.exists() || !file.isDirectory()) {
            //noinspection ResultOfMethodCallIgnored
            file.mkdirs();
        }

        DownloadImpl.getInstance(context)
                .with(bean.downloadUrl)
                .setEnableIndicator(true)
                .autoOpenWithMD5(bean.fileMd5)
                .setUniquePath(false)
                .setQuickProgress(true)
                .setParallelDownload(false)
                .setOpenBreakPointDownload(false)
                .setRetry(0)
                .target(file, ContextHolder.getAppContext().getPackageName() + ".provider")
                .enqueue(new DownloadListenerAdapter() {
                    @Override
                    public void onStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength, Extra extra) {
                        Toast.makeText(context, "正在下载安装包, 请到通知栏看下载进度", Toast.LENGTH_SHORT).show();
                        super.onStart(url, userAgent, contentDisposition, mimetype, contentLength, extra);
                    }

                    @Override
                    public void onProgress(String url, long downloaded, long length, long usedTime) {
                        super.onProgress(url, downloaded, length, usedTime);
                    }

                    @Override
                    public boolean onResult(Throwable throwable, Uri path, String url, Extra extra) {
                        if (throwable != null) {
                            //noinspection ResultOfMethodCallIgnored
                            ((DownloadTask) extra).getFile().delete();
                            int status = ((DownloadTask) extra).getStatus();
                            if (status == DownloadTask.STATUS_CANCELED) {
                                Toast.makeText(context, "下载已取消", Toast.LENGTH_SHORT).show();
                            } else if (status == DownloadTask.STATUS_ERROR) {
                                Toast.makeText(context, "下载失败: " + throwable.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                            return true;
                        }
                        return super.onResult(null, path, url, extra);
                    }
                });

    }


    @Keep
    private static final class UpdateBean {

        public int versionCode;
        public String versionName;
        public String fileMd5;
        public String downloadUrl;
        public List<String> changeLog;
        public boolean hasUpdate;

    }

}
